#! /usr/bin/env python
# -*- coding:utf-8 -*-
from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import urllib.request
import urllib.parse
import json
import binascii
import random

class WYYMusic(object):
    def __init__(self):
        self.url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='
        self.header = {
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9",
            "content-type": "application/x-www-form-urlencoded",
            "cookie": "_iuqxldmzr_=32; _ntes_nnid=fd0e158e7adb1b3e53c310ebeb58d77d,1564830032177; _ntes_nuid=fd0e158e7adb1b3e53c310ebeb58d77d; playerid=69204524; JSESSIONID-WYYY=%5Ce%2BJkuPpde91iGjV30dXl56CPigWXpOwpg21A%5CwOCPNzYkRcGtw%2Br20UoKlQDjQbG2%2BcK%2FGpWHRn34WwzNWUEfjpgtbaifGaNryyEqoZOFW6EeWrm2nj41XDldbIeWshK3oKnfmQjT7Vkth4PUIpPjrsdAGqoAG5l4I8453Mw9Fdsvb0%3A1564837522441",
            "origin": "https://music.163.com",
            "referer": "https://music.163.com/",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
        }
        self.data = {
            "params": "",
            "encSecKey": ""
        }
        
        self.id = ""
        self.key = ""
        self.encSecKey = ""

        self.d = ""
        self.e = "010001"
        self.f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
        self.g = "0CoJUm6Qyw8W8jud"
        
    def funa(self, num):
        b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        c = ""
        for index in range(0, num):
            c += b[random.randint(0, len(b)-1)]
        return c

    def funb(self, a, b):
        key = b.encode()
        iv = b'0102030405060708'
        data = a.encode()
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        data = cipher.encrypt(pad(data, AES.block_size))
        return b64encode(data).decode()
        
    def func(self, ran_key, pub_key, modulus):
        text = ran_key[::-1]
        rsa = int(binascii.hexlify(text.encode()), 16) ** int(pub_key, 16) % int(modulus, 16)
        return format(rsa, 'x').zfill(256)

    def fund(self, d, g):
        self.key = self.funa(16)
        encText = self.funb(d, g)
        encText = self.funb(encText, self.key)
        encSecKey = self.func(self.key, self.e, self.f)
        return encText, encSecKey

    def update_id(self, song_id):
        self.id = song_id

    def cal_params(self):
        self.data['params'], self.data['encSecKey'] = self.fund(self.d, self.g)

    def get_download_url(self):
        self.d = f'{{"ids":"[{self.id}]","level":"standard","encodeType":"aac","csrf_token":""}}'
        self.cal_params()
        req = urllib.request.Request(url=self.url, data=urllib.parse.urlencode(self.data).encode('utf-8'), headers=self.header)
        response = json.loads(urllib.request.urlopen(req).read().decode('utf-8'))
        print(response['data'][0]['url'])

if __name__ == '__main__':
    wy = WYYMusic()
    wy.update_id('1361144868')
    wy.get_download_url()
